from __future__ import annotations

import asyncio
from logging.config import fileConfig
from alembic import context
from sqlalchemy import engine_from_config, pool
from sqlalchemy.ext.asyncio import create_async_engine

from app.core.config import settings
from app.db.base import Base  # noqa: F401  确保模型元数据被加载

config = context.config
if config.config_file_name is not None:
  fileConfig(config.config_file_name)

section = config.get_section(config.config_ini_section)
if section is None:
  raise RuntimeError('Alembic config section missing')
section['sqlalchemy.url'] = settings.mysql_sync_url

ASYNCHRONOUS = settings.mysql_async_url.startswith('mysql+asyncmy')

target_metadata = Base.metadata


def run_migrations_offline() -> None:
  url = section['sqlalchemy.url']
  context.configure(
    url=url,
    target_metadata=target_metadata,
    literal_binds=True,
    compare_type=True,
    compare_server_default=True,
  )

  with context.begin_transaction():
    context.run_migrations()


def do_run_migrations(connection) -> None:
  context.configure(
    connection=connection,
    target_metadata=target_metadata,
    compare_type=True,
    compare_server_default=True,
  )

  with context.begin_transaction():
    context.run_migrations()


def run_migrations_online() -> None:
  if not ASYNCHRONOUS:
    connectable = engine_from_config(
      section,
      prefix='sqlalchemy.',
      poolclass=pool.NullPool,
    )
    with connectable.connect() as connection:
      do_run_migrations(connection)
    return

  async def async_main() -> None:
    connectable = create_async_engine(settings.mysql_async_url, poolclass=pool.NullPool)
    async with connectable.connect() as connection:
      await connection.run_sync(do_run_migrations)

  asyncio.run(async_main())


if context.is_offline_mode():
  run_migrations_offline()
else:
  run_migrations_online()
